package  com.wandian.texas;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Event;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

/**
 * 客户端
 */
public class ChatClient extends JFrame{

	private static final long serialVersionUID = -8536844369570721300L;

	private Socket socket;
	private DataInputStream bis;
	private DataOutputStream dos;
	private JFrame frame;
	private JPanel centerPanel;
	private JPanel buttonPanel1;
	private JPanel buttonPanel2;
	private JLabel addressLabel;
	private JLabel portLabel;
	private JTextField addressField;
	private JTextField portField;
	private JButton linkButton;
	private JLabel msg1;
	private JLabel msg2;
	private DefaultListModel listModel;
	private JScrollPane scrollPane;
	private JList msgArea1;
	private JTextField msgField;
	private JButton sendButton;
	
	private static final int WIDTH = 400;
	private static final int HEIGHT = 400;
	private boolean connected = false;
	private boolean start;
	
	//初始化客户端窗口
	public void init(){
		//创建客户端窗口
		frame = new JFrame("客户端");
		frame.setResizable(false);
		int screenWidth = (int) java.awt.Toolkit.getDefaultToolkit().getScreenSize().getWidth();
		int screenHeight = (int) java.awt.Toolkit.getDefaultToolkit().getScreenSize().getHeight();
		frame.setBounds((screenWidth-WIDTH)/2, (screenHeight-HEIGHT)/2, WIDTH, HEIGHT);
		
		addressLabel =  new JLabel("地址：");
		portLabel = new JLabel("端口：");
		addressField = new JTextField(10);
		portField = new JTextField(10);
		linkButton = new JButton("连接");
		msg1 = new JLabel("接收的消息：");
		msg2 = new JLabel("发送的消息：");
		listModel = new DefaultListModel();
		msgArea1 = new JList(listModel);
		scrollPane = new JScrollPane(msgArea1);
		listModel.addElement("#客户端消息：");
		new Scroller().start();
		msgArea1.setBackground(Color.YELLOW);
		msgField = new JTextField(25);
		sendButton = new JButton("发送");
		buttonPanel1 = new JPanel(new BorderLayout());
		buttonPanel2 = new JPanel(new BorderLayout());
		
		addressLabel.setBounds(new Rectangle(10,10,40,20));
		addressField.setBounds(new Rectangle(50,10,100,20));
		portLabel.setBounds(new Rectangle(160,10,40,20));
		portField.setBounds(new Rectangle(200,10,80,20));
		buttonPanel1.setBounds(new Rectangle(290,10,60,20));
		buttonPanel1.add(linkButton,BorderLayout.CENTER);
		msg1.setBounds(new Rectangle(10,50,350,20));
		scrollPane.setBounds(new Rectangle(10,80,372,200));
		msg2.setBounds(new Rectangle(10,290,350,20));
		msgField.setBounds(new Rectangle(10,320,280,20));
		buttonPanel2.setBounds(new Rectangle(300,320,60,20));
		buttonPanel2.add(sendButton,BorderLayout.CENTER);
		
		
		centerPanel = (JPanel) frame.getContentPane();
		centerPanel.setLayout(null);
		
		centerPanel.add(addressLabel);
		centerPanel.add(addressField);
		centerPanel.add(portLabel);
		centerPanel.add(portField);
		centerPanel.add(buttonPanel1);
		centerPanel.add(msg1);
		centerPanel.add(scrollPane);
		centerPanel.add(msg2);
		centerPanel.add(msgField);
		centerPanel.add(buttonPanel2);
		
		// 设置窗口可见
		frame.setVisible(true);
		
		//注册连接按钮的鼠标事件
		linkButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				String address = addressField.getText();
				String portStr = portField.getText();
				int port = Integer.valueOf(portStr);
				Pattern addressPattern = Pattern.compile("^\\d+\\.\\d+\\.\\d+\\.\\d+$");
				Matcher addressMatcher = addressPattern.matcher(address);
				if(!addressMatcher.matches()){
					JOptionPane.showMessageDialog(null, "Ip地址输入的格式不正确！");
					return;
				}else if(port<9000 || port>65535){
					JOptionPane.showMessageDialog(null, "端口为不小于9000且不大于65535的整数，请正确的输入！");
					return;
				}else{
					link(address,port);
				}
			}
		});
		//注册发送按钮的鼠标事件
		sendButton.addMouseListener(new MouseAdapter(){
			@Override
			public void mouseClicked(MouseEvent e) {
				String command = msgField.getText().trim();
				if(command!=null && !command.equals("")){
					sendMsg(command);
				}
				msgField.setText("");
			}
		});
		
		//注册窗口事件
		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				dispose();
				System.exit(0);
			}
		});
		
		//注册回车事件
		msgField.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if(e.getKeyCode()==Event.ENTER){
					String command = msgField.getText().trim();
					if(command!=null && !command.equals("")){
						sendMsg(command);
					}
					msgField.setText("");
				}
			}
		});
	}
	
	//创建连接
	public void link(String address,int port){
		try {
			socket = new Socket(address,port);
			connected = true;
			bis = new DataInputStream(socket.getInputStream());
			dos = new DataOutputStream(socket.getOutputStream());
			new Receiver().start();
			addressField.setText("");
			portField.setText("");
		}catch (ConnectException e) {
			System.out.println("#无法连接服务器，请检查端口是否填写正确！");
			listModel.addElement("#无法连接服务器，请检查端口是否填写正确！");
		}catch (UnknownHostException e) {
			System.out.println("#无法连接服务器，请检查地址是否填写正确！");
			listModel.addElement("#无法连接服务器，请检查地址是否填写正确！");
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//发消息
	public void sendMsg(String msg){
		try {
			dos.writeUTF(msg);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//接受消息
	public String receiveMsg(){
		String msg;
		try {
			msg = bis.readUTF();
			return msg;
		}catch (SocketException e) {
			connected = false;
			System.out.println("#服务器已经关闭");
			listModel.addElement("#服务器已经关闭");
			return null;
		}catch (IOException e) {
			return null;
		}
	}
	
	//接受消息的线程类
	class Receiver extends Thread{
		public void run() {
			while(connected){
				String msg = receiveMsg();
				if(msg!=null && !msg.equals("")){
					listModel.addElement(msg);
				}
			}
		}
	}
	

	
	public boolean isStart() {
		return start;
	}

	public void setStart(boolean start) {
		this.start = start;
	}
	
	public Socket getSocket() {
		return socket;
	}

	public void setSocket(Socket socket) {
		this.socket = socket;
	}

	//负责滚动的线程
	class Scroller extends Thread{
		@Override
		public void run() {
			while(true){
				scrollToView();
			}
		}
	}
	
	//Jlist的滚动方法
	 private void scrollToView(){
	        int lastIndex = listModel.getSize();
	        Rectangle rect=msgArea1.getCellBounds(lastIndex-1,lastIndex-1);
	        scrollPane.getViewport().scrollRectToVisible(rect);
	    }
	
	public static void main(String[] args) {
		new ChatClient().init();
	}
}
